package independence.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
/**
 * Serves as a template base for creating DAO's. Extend this class to tap into
 * DAO-pattern access to creating, reading, updating, and deleting objects 
 * persisted in a database from Hibernate. For explicitly-typed data access objects,
 * extend {@link independence.hibernate.GenericDAOImpl} which allows DAO's to be strictly
 * bound to a single type. 
 * 
 * @author TK, TK Assembled for Independence Honor.
 */
public class IndyDAOImpl implements IndyDAO {
	/**
	 * This instance's <code>HibernateTemplate</code> object.
	 */
	private HibernateTemplate hibernateTemplate;
	/**
	 * {@inheritDoc}
	 */
	@Override public Session getSession() {
		return (!hibernateTemplate.isAllowCreate() ? SessionFactoryUtils.getSession(hibernateTemplate.getSessionFactory(), false) 
				: SessionFactoryUtils.getSession(hibernateTemplate.getSessionFactory(),
						hibernateTemplate.getEntityInterceptor(), hibernateTemplate.getJdbcExceptionTranslator()));
	}
	/**
	 * {@inheritDoc}
	 */
	@Override public void releaseSession(Session value) {
		SessionFactoryUtils.releaseSession(value, hibernateTemplate.getSessionFactory());
	}
	/**
	 * {@inheritDoc}
	 */
	@Override public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override public void setHibernateTemplate(HibernateTemplate value) {
		this.hibernateTemplate = value;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override public SessionFactory getSessionFactory() {
		return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override public void setSessionFactory(SessionFactory value) {
		if (this.hibernateTemplate == null || 
				value != this.hibernateTemplate.getSessionFactory()) {
			this.hibernateTemplate = createHibernateTemplate(value);
		}
	}
	/**
	 * Creates a <code>HibernateTemplate</code> object from the supplied <code>SessionFactory</code>.
	 * @param	value	The <code>SessionFactory</code> to create the <code>HibernateTemplate</code> from.
	 * @return	The newly created <code>HibernateTemplate</code> object.
	 */
	protected HibernateTemplate createHibernateTemplate(SessionFactory value) {
		return new HibernateTemplate(value);
	}
	/**
	 * Checks the DAO's configuration and throws errors if the DAO is not configured correctly. 
	 * @throws IllegalArgumentException	If the configuration is invalid, a InvalidArgumentException is thrown.
	 */
	protected void checkDaoConfig() {
		if(this.hibernateTemplate == null) {
			throw new IllegalArgumentException("The DAO configuration in IndyDAOImpl is invalid:" +
					" no SessionFactory or HibernateTemplate was passed in.");
		}
	}
	
}
